﻿// =====================================================================
//
//  This file is part of the Microsoft Dynamics CRM SDK code samples.
//
//  Copyright (C) Microsoft Corporation.  All rights reserved.
//
//  This source code is intended only as a supplement to Microsoft
//  Development Tools and/or on-line documentation.  See these other
//  materials for detailed information regarding Microsoft code samples.
//
//  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
//  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
//  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
//  PARTICULAR PURPOSE.
//
// =====================================================================

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Security.Principal;

namespace SL.IdentityModel.Claims
{
	/// <summary>
	/// This class implements IClaimsIdentity to represent a claims based identity
	/// </summary>
	public class ClaimsIdentity : IClaimsIdentity, IIdentity
	{
		private string _authMethodClaimType;
		private ClaimCollection _claims;
		private string _nameClaimType;
		private string _roleClaimType;

		public event PropertyChangedEventHandler PropertyChanged;

		/// <summary>
		/// Creates a ClaimsIdentity class with no initialized claims
		/// </summary>
		public ClaimsIdentity()
			: this((IEnumerable<Claim>)null)
		{ }

		/// <summary>
		/// Creates a ClaimsIdentity class with initialized claim values
		/// </summary>
		/// <param name="claims">sets Claims</param>
		public ClaimsIdentity(IEnumerable<Claim> claims)
		{
			_nameClaimType = ClaimType.Name;
			_roleClaimType = ClaimType.Role;
			_authMethodClaimType = ClaimType.AuthenticationMethod;
			_claims = new ClaimCollection();

			if (null != claims)
			{
				_claims.AddRange(claims);
			}

			NotifyPropertyChanged("Name");
			NotifyPropertyChanged("IsAuthenticated");
			NotifyPropertyChanged("AuthenticationType");
		}

		private void NotifyPropertyChanged(String info)
		{
			if (PropertyChanged != null)
			{
				PropertyChanged(this, new PropertyChangedEventArgs(info));
			}
		}

		#region IClaimsIdentity

		public ClaimCollection Claims
		{
			get { return _claims; }
		}

		public string RoleClaimType
		{
			get { return _roleClaimType; }
			set { _roleClaimType = value; }
		}

		public string NameClaimType
		{
			get { return _nameClaimType; }
			set { _nameClaimType = value; }

		}

		#endregion

		#region IIdentity


		/// <summary>
		/// returns value of claim with type ClaimType.AuthenticationMethod. This is the authentication method used at the STS
		/// </summary>
		public string AuthenticationType
		{
			get
			{
				Claim claim = (from c in _claims
							   where c.ClaimType == _authMethodClaimType
							   select c).FirstOrDefault<Claim>();

				return null == claim ? null : claim.Value;
			}
		}

		public bool IsAuthenticated
		{
			get { return (_claims.Count > 0); }
		}

		public string Name
		{
			get
			{
				Claim claim = (from c in _claims
							   where c.ClaimType == _nameClaimType
							   select c).FirstOrDefault<Claim>();

				return null == claim ? null : claim.Value;
			}
		}

		#endregion
	}
}
